package io.gitee.guoguoleo.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import io.gitee.guoguoleo.annotation.JokerField;
import io.gitee.guoguoleo.annotation.JokerId;
import io.gitee.guoguoleo.annotation.JokerIgnore;
import io.gitee.guoguoleo.annotation.JokerLogic;
import io.gitee.guoguoleo.enums.FieldFill;
import io.gitee.guoguoleo.model.FieldInfo;
import io.gitee.guoguoleo.model.FieldList;
import io.gitee.guoguoleo.properties.JokerProperties;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class FieldUtil {

    /**
     * 整理所有字段
     *
     * @param clazz 实体类
     * @return 字段信息对象
     */
    public static FieldList getAllField(Class<?> clazz) {
        FieldList fieldList = new FieldList();
        List<FieldInfo> fieldInfoList = new CopyOnWriteArrayList<>();

        List<FieldInfo> insertFillFieldList = new CopyOnWriteArrayList<>();
        List<FieldInfo> updateFillFieldList = new CopyOnWriteArrayList<>();

        JokerProperties jokerProperties = SpringUtil.getBean(JokerProperties.class);
        if (StringUtils.isNotBlank(jokerProperties.getDelField())) {
            FieldInfo fieldInfo = new FieldInfo()
                    .setFieldName(jokerProperties.getDelField());//属性值的名称
            fieldList.setDelField(fieldInfo);
        }


        Class<?> currClass = clazz;
        while (currClass != null) {
            Field[] fields = currClass.getDeclaredFields();
            for (Field field : fields) {
                //region 字段忽略
                JokerIgnore jokerIgnore = field.getAnnotation(JokerIgnore.class);
                if (jokerIgnore != null && jokerIgnore.ignore()) {
                    continue;
                }
                //endregion


                FieldInfo fieldInfo = new FieldInfo()
                        .setFieldName(field.getName())//属性值的名称
                        .setField(field);


                JokerField jokerField = field.getAnnotation(JokerField.class);
                if (jokerField != null && StringUtils.isNotBlank(jokerField.value())) {
                    fieldInfo.setSqlFieldName(jokerField.value());
                } else {
                    fieldInfo.setSqlFieldName(FieldUtil.toField(field.getName()));
                }
                //region 新增填充
                if (jokerField != null && jokerField.fill().equals(FieldFill.INSERT)) {
                    insertFillFieldList.add(fieldInfo);
                }
                //endregion

                //region 更新填充
                if (jokerField != null && jokerField.fill().equals(FieldFill.UPDATE)) {
                    updateFillFieldList.add(fieldInfo);
                }
                //endregion

                //region 逻辑删除字段处理
                if (fieldList.getDelField() != null) {
                    String fieldName = fieldList.getDelField().getFieldName();
                    if (fieldName.equals(field.getName())) {
                        fieldList.getDelField()
                                .setSqlFieldName(fieldInfo.getSqlFieldName())
                                .setField(field);
                    }
                } else {
                    JokerLogic jokerLogic = field.getAnnotation(JokerLogic.class);
                    if (jokerLogic != null) {
                        fieldList.setDelField(fieldInfo);
                    }
                }
                //endregion

                //region id列表
                JokerId jokerId = field.getAnnotation(JokerId.class);
                if (jokerId != null) {
                    if (StringUtils.isNotBlank(jokerId.value())) {
                        fieldInfo.setSqlFieldName(jokerId.value());
                    }
                    fieldList.setIdField(fieldInfo);
                }
                //endregion




                fieldInfoList.add(fieldInfo);
            }


            currClass = currClass.getSuperclass();
        }
        fieldList.setAllFieldInfoList(fieldInfoList);
        fieldList.setInsertFillFieldList(insertFillFieldList);
        fieldList.setUpdateFillFieldList(updateFillFieldList);

        return fieldList;
    }


    public static String toField(String fieldName) {
        JokerProperties jokerProperties = SpringUtil.getBean(JokerProperties.class);
        if (jokerProperties.getUnderLineField()) {
            return StrUtil.toUnderlineCase(fieldName);
        } else {
            return StrUtil.toCamelCase(fieldName);
        }
    }

}
